package com.luobd.bpm.common.process;

import com.google.common.collect.Maps;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.bpmn.model.FlowElement;
import org.activiti.engine.ActivitiException;
import org.activiti.engine.impl.context.Context;
import org.activiti.engine.impl.interceptor.CommandContext;
import org.activiti.engine.impl.persistence.entity.ExecutionEntity;
import org.activiti.engine.impl.persistence.entity.ExecutionEntityManager;
import org.activiti.engine.impl.util.ProcessDefinitionUtil;

import java.util.List;
import java.util.Map;

public class DynamicStateManager {

    public ExecutionEntity resolveActiveExecution(String processInstanceId, String activityId, CommandContext commandContext) {
        ExecutionEntityManager executionEntityManager = commandContext.getExecutionEntityManager();
        ExecutionEntity executionEntity = executionEntityManager.findById(processInstanceId);
        if(executionEntity == null) {
            throw new ActivitiException("当前流程实例未找到执行中任务");
        }
        if(!executionEntity.isProcessInstanceType()) {
            throw new ActivitiException("当前执行任务不是流程实例类型");
        }
        ExecutionEntity activeExecutionEntity = null;
        List<ExecutionEntity> executions = executionEntityManager.findChildExecutionsByProcessInstanceId(executionEntity.getProcessInstanceId());
        for (ExecutionEntity entity : executions) {
            if(entity.getCurrentActivityId().equals(activityId)) {
                activeExecutionEntity = entity;
                break;
            }
        }
        if(activeExecutionEntity == null) {
            throw new ActivitiException("当前活动id未找到运行中的实例");
        }
        return activeExecutionEntity;
    }


    public void moveExecutionState(List<ExecutionEntity> currentExecutions,String moveToActivityId,CommandContext commandContext) {
        ExecutionEntityManager executionEntityManager = commandContext.getExecutionEntityManager();
        ExecutionEntity executionEntity = currentExecutions.get(0);
        BpmnModel bpmnModel = ProcessDefinitionUtil.getBpmnModel(executionEntity.getProcessDefinitionId());
        FlowElement flowElement = bpmnModel.getFlowElement(moveToActivityId);
        if(flowElement == null) {
            throw new ActivitiException("Activity could not be found process definition for id " + moveToActivityId);
        }
        Map<String,ExecutionEntity> continueParentExecutionMap = Maps.newHashMap();
        for (ExecutionEntity entity : currentExecutions) {
            if(entity.getParentId() == null) {
                throw new ActivitiException("Execution has no parent execution " + entity.getParentId());
            }
            ExecutionEntity parentEntity = executionEntityManager.findById(entity.getParentId());
            continueParentExecutionMap.put(entity.getId(),parentEntity);
        }

        // 删除当前结点所在的执行实例及相关数据
        for (ExecutionEntity execution : currentExecutions) {
            executionEntityManager.deleteExecutionAndRelatedData(execution,"Change activity to " + flowElement.getId(),false);
        }

        ExecutionEntity defaultParentExecution = continueParentExecutionMap.get(currentExecutions.get(0).getId());
        ExecutionEntity childExecution = executionEntityManager.createChildExecution(defaultParentExecution);
        // 设置子执行实例的当前活动结点未撤回的目标结点
        childExecution.setCurrentFlowElement(flowElement);
        // 向operations中压入继续流程的操作类
        Context.getAgenda().planContinueProcessOperation(childExecution);

    }








}
